package com.cskaoyan.service.authservice;

import com.cskaoyan.bean.PermInfo;
import com.cskaoyan.bean.PermInfoExample;
import com.cskaoyan.mapper.PermInfoMapper;
import com.cskaoyan.mapper.systemmapper.AdminMapper;
import com.cskaoyan.mapper.systemmapper.PermissionMapper;
import com.cskaoyan.mapper.systemmapper.RoleMapper;
import com.cskaoyan.realm.MallToken;
import com.cskaoyan.vo.LoginVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author hsp
 * @date 2021/5/12 10:15
 */
@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    PermInfoMapper permInfoMapper;
    @Override
    public LoginVo info(String token) {
        String username = (String) SecurityUtils.getSubject().getSession().getAttribute("adminName");
        String avatar = adminMapper.selectAvatarByUsername(username);
        List<String> roles = selectRolesByUsername(username);
        List<String> tempPerms = selectPermissonsByUsername(username);
//        amdin:topic:read  ---> GET admin/topic/read
        List<String> perms = tempPermsToPermApi(tempPerms);
        LoginVo loginVo = new LoginVo();
        loginVo.setName(username);
        loginVo.setAvatar(avatar);
        loginVo.setRoles(roles);
        loginVo.setPerms(perms);
        return loginVo;
    }

    public List<String> tempPermsToPermApi(List<String> tempPerms) {

        List<String> permApis = new ArrayList<>();
        for (String tempPerm : tempPerms) {
            PermInfoExample permInfoExample = new PermInfoExample();
            permInfoExample.createCriteria().andPermNameEqualTo(tempPerm);
            List<PermInfo> permInfos = permInfoMapper.selectByExample(permInfoExample);
            String permApi = permInfos.get(0).getPermApi();
            permApis.add(permApi);
        }

        return permApis;
    }

    @Override
    public String login(Map map) {

        String username = (String) map.get("username");
        String password = (String) map.get("password");
        Subject subject = SecurityUtils.getSubject();

//        subject.getSession().setAttribute("UserOrAdmin","admin");
        MallToken adminMallToken = new MallToken(username, password, "admin");
        subject.login(adminMallToken);
        Serializable id = subject.getSession().getId();
        subject.getSession().setAttribute("adminName",username);


        return id.toString();
    }

    public List<String> selectRolesByUsername(String username){
        String roleIds = adminMapper.selectRoleIdsByUsername(username);
        ObjectMapper objectMapper = new ObjectMapper();
        List<String> roles = null;
        Integer[] roleIdsInt ;
        if (roleIds!=null){
            try {
                roleIdsInt = objectMapper.readValue(roleIds, Integer[].class);
                roles = roleMapper.selectRoleNameByRoleIds(roleIdsInt);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return roles;
    }

    public List<String> selectPermissonsByUsername(String username){
        String roleIds = adminMapper.selectRoleIdsByUsername(username);
        ObjectMapper objectMapper = new ObjectMapper();
        Integer[] roleIdsInt = null;
        if (roleIds!=null){
            try {
                roleIdsInt = objectMapper.readValue(roleIds, Integer[].class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        List<String> perms ;
        List<Integer> integers = Arrays.asList(roleIdsInt);
        perms = permissionMapper.selectPermissonsByRoleIds(integers);
        return perms;
    }
}
